package meta.entity

import com.google.gson.*
import kotlinx.serialization.Serializable
import kotlin.reflect.KFunction
import kotlin.reflect.full.memberFunctions
import kotlin.reflect.full.memberProperties
import kotlin.reflect.jvm.isAccessible

enum class MetaSets {
    Station, InlineSwitch, Transformer, OutlineSwitch, ChargingPile, ContactSwitch,
    Diesel, Photovoltaic, BatteryStation, BuildingLoad, FloorLoad, RoomLoad, Appliance
}

data class BuildingInitEntity(
    val name: String,
    val batchCreate: Boolean,
    val floor: Int,
    val positionName: String,
    val enCode: String,
    val roomNumberList: List<Int> ?= null,
    val roomStringList: List<String> ?= null,
    val applianceList: List<String>
)

@Serializable
abstract class MetaEntity {
    abstract var id:String
    abstract var name:String
    abstract var code:String
}

@Serializable
sealed interface TreeModel<T> {
    var parentId : String
    var parentPath : String
    var children : MutableList<T>
    fun getRoute() : String
    fun appendChild(t: T)
    fun deleteChild(id: String)
    fun findChild(id: String) : T?
}

@Serializable
sealed class MetaTree() : MetaEntity(), TreeModel<MetaTree>{

    override fun getRoute(): String {
        return if (parentPath == "-1") "root" else "${this.parentPath} -> ${this.id}"
    }

    override fun findChild(name: String) : MetaTree? {
        return this.children.find { it.name == name }
    }

    override fun deleteChild(id: String) {
        this.children.removeIf { it.name == id }
    }

    override fun appendChild(t: MetaTree) {
        this.children.add(t)
    }

    fun printTree() {
        val recursionList = mutableListOf(this)
        println("-------------- 按照树形结构打印 $name -----------------")
        while (recursionList.size > 0){
            val curNode = recursionList[0]
            print("(节点: ${curNode.name} | 路径 ${curNode.getRoute()})")
            recursionList.removeAt(0)
            curNode.children.forEach { recursionList.add(it) }
            println()
        }
        println("---------------------   end   -----------------------")
    }

    // 提供一种额外的调用方法，也可以强制转换对象类型，然后直接调用
    fun funcs() : Map<String, KFunction<*>> {
        val functionMap = mutableMapOf<String, KFunction<*>>()
        this::class.memberFunctions.forEach {
            functionMap[it.name] = it
        }
        return functionMap.toMap()
    }
}

interface MetaMaster {
    val entity : MetaTree

    companion object {
        // 针对海南电校配电系统的结构，刻画成树形结构
        fun parkInstance(me: MetaTree): MetaMaster = when (me) {
            is Station -> StationFactory(me)
            is InlineSwitch -> InlineSwitchFactory(me)
            is Transformer -> TransformerFactory(me)
            is OutlineSwitch -> TransformerFactory(me)
            is ChargingPile -> ChargingPileFactory(me)
            is ContactSwitch -> ContactSwitchFactory(me)
            is Diesel -> DieselFactory(me)
            is Photovoltaic -> PhotovoltaicFactory(me)
            is BatteryStation -> BatteryStationFactory(me)
            is BuildingLoad -> BuildingLoadFactory(me)
            is FloorLoad -> FloorLoadFactory(me)
            is RoomLoad -> RoomLoadFactory(me)
            is Appliance -> ApplianceFactory(me)
        }
        // 当逻辑发生变化时，可以重新构建工厂方法
        fun otherInstance() {}
    }
}

fun MetaEntity.print() {
    println("-----------  this is Station -------------")
    this::class.memberProperties.forEach {
        it.isAccessible = true
        print("(${it.name} : ${it.call(this)})")
    }
    println()
    println("------------------------------------------")
}


fun main(args: Array<String>) {
    // station 等不同entity的初始化应在setup中去考虑
    val s = Station("1", "2", "3", "root", mutableListOf(), "")
    val meta = MetaMaster.parkInstance(s)

    println(meta.entity.funcs()["getRoute"]?.call(meta.entity))
}
